#pragma once


#define CACHE_INSTANCE_NUMBER 5

class CCache;
static std::map<int, CCache*> CacheMap = std::map<int, CCache*>();

class CCache
{
private:
    static CCache* m_lpInstance;
    static int m_nInstanceCnt;
    static std::mutex m_Mutex;

private:
    CCache() { std::cout << "CCache" << std::endl; }
    virtual ~CCache()
    {
        std::cout << "~CCache" << std::endl;
    }

	CCache(const CCache&) {}
	CCache& operator=(const CCache&) {}

public:
    static CCache* GetInstance()
    {
        m_lpInstance = CacheMap[m_nInstanceCnt];

        if (!m_lpInstance)
        {
            m_Mutex.lock();

            if (!m_lpInstance)
            {
                m_lpInstance = new CCache;
                CacheMap[m_nInstanceCnt] = m_lpInstance;
            }

            m_Mutex.unlock();
        }

        m_Mutex.lock();

        m_nInstanceCnt++;
        if (m_nInstanceCnt > CACHE_INSTANCE_NUMBER)
            m_nInstanceCnt = 1;

        m_Mutex.unlock();

        return m_lpInstance;
    }

private:
    class CGarb
    {
    public:
        virtual ~CGarb()
        {
            if (m_lpInstance)
            {
                for (int i = 1; i <= CACHE_INSTANCE_NUMBER; i++)
                {
                    std::cout << "~CGarb" << std::endl;
                    m_lpInstance = CacheMap[i];
                    delete m_lpInstance;
                }
            }
        }
    };
    static CGarb m_Gc;
};

CCache* CCache::m_lpInstance = nullptr;
int CCache::m_nInstanceCnt = 1;
CCache::CGarb CCache::m_Gc;
std::mutex CCache::m_Mutex;

